import { G6, I_editor, N_oFlowchart, ifs } from '../config';

class T_graphToolbar {
  private _oFlowchart: any = undefined;

  private G_grid: any = null;

  private G_itemAlignType: any = null;

  private G_compID: string;

  private _editor: I_editor = undefined;

  private GT_compBox: ifs.I_compBox = undefined;

  constructor(compBoxInfo: ifs.I_compBoxInfo) {
    this.G_compID = compBoxInfo.compID;
    this.GT_compBox = compBoxInfo.TcompBox;
  }

  public get G_oFlowchart(): any {
    if (!this._oFlowchart) {
      this._oFlowchart = this.GT_compBox.getCompMergeName(
        this.G_compID,
        `oFlowchart`
      );
    }
    return this._oFlowchart;
  }

  get GT_editor(): I_editor {
    if (!this._editor) {
      this._editor = this.GT_compBox.getCompMergeName(this.G_compID, `editor`);
    }
    return this._editor;
  }

  private btnUndo = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    // G6规定要大于两个记录才可以撤销
    // 调用插件逻辑
    return new Promise(resolve => {
      this.GT_compBox.getCompMergeName(this.G_compID, `g6Toolbar`).undo();
      resolve(true);
    });
  };

  private btnRedo = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    // G6规定要大于两个记录才可以撤销
    // 调用插件逻辑
    return new Promise(resolve => {
      this.GT_compBox.getCompMergeName(this.G_compID, `g6Toolbar`).redo();
      resolve(true);
    });
  };

  private btnOpen = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolve => {
      // this.G_oFlowchart.onGraphOpenData(this.doOpenDataHandle);
      resolve(true);
    });
  };

  // 审核
  private btnAudit = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolve => {
      resolve(true);
    });
  };

  // 反审核
  private btnUnAudit = (
    obj?: N_oFlowchart.I_toolbarClick
  ): Promise<boolean> => {
    return new Promise(resolve => {
      resolve(true);
    });
  };

  private btnNavMap = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolve => {
      this.changeNavMapState(obj.key);
      resolve(true);
    });
  };

  private fullScreen = (
    obj?: N_oFlowchart.I_toolbarClick
  ): Promise<boolean> => {
    return new Promise(resolve => {
      resolve(true);
    });
  };

  private changeNavMapState(name: string) {
    const L_graph = this.GT_editor.G_graph;
    const L_editToolbar = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `editToolbar`
    );
    const L_isOpen: boolean = L_editToolbar.G_toolMap.get(name).isOpen;

    this.GT_editor.G_oFlowchart.showMap = !L_isOpen;

    this.setBtnChickedStyle(name, !L_isOpen);
  }

  // 新增
  private btnNew = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolv => {
      this.GT_editor.initGraph();
      this.setNewMode();
      resolv(true);
    });
  };

  private setNewMode() {
    this.GT_compBox.getCompMergeName(this.G_compID, `item`).setItemDisabledAll(
      false
    );
    // 编辑模式
    this.setBtnDisabled(`new`, true);
    this.setBtnDisabled(`layout`, false); // 排版
    this.setBtnDisabled(`save`, false);
    // this.setBtnDisabled(`edit`, true);
    this.setEditBtnDisabled(true);
    this.setAuditBtnDisabled(true, `all`);
    this.GT_editor.setGraphMode(`edit`);
    this.GT_editor.editorState = `new`; // state 事件在set时发送
    this.GT_editor.G_oFlowchart.isExpand = true;
  }

  public setToolbarViewMode() {
    // 浏览模式
    this.setBtnDisabled(`new`, true);
    this.setBtnDisabled(`layout`, false); // 排版
    this.setBtnDisabled(`save`, true);
    this.setBtnDisabled(`edit`, true);
    this.setAuditBtnDisabled(true, `all`);
    this.GT_editor.editorState = `none`; // state 事件在set时发送
    this.GT_editor.G_oFlowchart.isExpand = false;
  }

  private btnEdit = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolv => {
      resolv(true);
    });
  };

  public setEditMode = () => {
    this.GT_compBox.getCompMergeName(this.G_compID, `item`).setItemDisabledAll(
      false
    );
    // 编辑模式
    this.setBtnDisabled(`save`, false);
    this.setBtnDisabled(`new`, true);
    this.GT_editor.setGraphMode(`edit`);
    this.setEditBtnDisabled(true);
    this.GT_editor.saveOldValue();
    this.setBtnDisabled(`layout`, false); // 排版
    this.GT_editor.editorState = `modify`;
    this.setAuditBtnDisabled(true, `all`);
    this.GT_editor.G_oFlowchart.isExpand = true;
  };

  public exitViewMode = () => {
    this.GT_compBox.getCompMergeName(this.G_compID, `item`).setItemDisabledAll(
      false
    );

    this.setBtnDisabled(`save`, true);
    this.setBtnDisabled(`new`, false);
    this.setBtnDisabled(`edit`, false);
    this.setBtnDisabled(`layout`, true); // 排版
    this.setAuditBtnDisabled(false);
  };

  //--------------------------------------------------------------
  // doLayout() {
  //   const L_graph = this.GT_compBox.getCompMergeName(this.G_compID,`graph`);
  //   L_graph.layout();
  // }
  private btnLayout = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolv => {
      const L_graph = this.GT_editor.G_graph;
      const maxNodeWidth = 100; // 节点的最大宽度
      const nodeDisX = 200; // 节点之间距离
      const nodeDisY = 200;
      const layoutLevelMap: Array<any> = [];
      const layoutLevelModel: Array<any> = [];
      const layoutInNodes: Array<any> = [];
      function layoutProcess(index, level) {
        // 是否有下一级需要处理
        let hasNextLevel = false;
        // 遍历所有上一级节点
        for (let i = 0; i < layoutLevelMap[index][level - 1].length; i++) {
          const node: any = layoutLevelMap[index][level - 1][i];
          const outEdges = node.getOutEdges();
          if (outEdges.length !== 0) {
            // 遍历上一级节点的出线
            for (let s = 0; s < outEdges.length; s++) {
              const edge = outEdges[s];
              // 获取该级节点的实例
              const targetNode = edge.getTarget();
              const targetModel = targetNode.getModel();
              // 如果这个节点未遍历过
              if (layoutInNodes.indexOf(targetModel.id) < 0) {
                if (!layoutLevelMap[index][level]) {
                  layoutLevelMap[index][level] = [];
                  layoutLevelModel[index][level] = [];
                }
                layoutInNodes.push(targetModel.id);
                hasNextLevel = true;
                layoutLevelMap[index][level].push(targetNode);
                layoutLevelModel[index][level].push(targetModel);
              }
            }
          }
        }
        // 进入下一级
        level++;
        if (hasNextLevel === true) layoutProcess(index, level);
      }
      // 定义起始节点（无入度节点）
      let index = 0;
      const items = L_graph.getNodes();
      items.forEach(item => {
        const inEdges = item.getInEdges();
        if (inEdges.length === 0) {
          const model = item.getModel();
          // 定义起始节点层（第一层）
          layoutLevelMap[index] = [];
          layoutLevelModel[index] = [];
          layoutLevelMap[index][0] = [];
          layoutLevelModel[index][0] = [];
          layoutLevelMap[index][0].push(item);
          layoutLevelModel[index][0].push(model);
          layoutInNodes.push(model.id);
          layoutProcess(index, 1);
          index++;
        }
      });
      const firstLength = layoutLevelMap.length;
      let currentWholeLevelPosX = 0;
      for (let x = 0; x < firstLength; x++) {
        const firstArr = layoutLevelModel[x];
        // 获取整体最大宽度
        // 节点最多的层的节点数
        const maxLength = layoutLevelMap[x].sort(function(a, b) {
          return b.length - a.length;
        })[0].length;
        // 节点最多层的宽度
        const maxWidth = maxLength * maxNodeWidth + (maxLength - 1) * nodeDisX;
        // 给各节点赋值新的xy
        let currentLevelPosY = 0;
        const secondLength = firstArr.length;
        for (let i = 0; i < secondLength; i++) {
          const secondArr = firstArr[i];
          const thirdLength = secondArr.length;
          let currentLevelPosX = currentWholeLevelPosX;
          const currentLevelDis =
            maxLength === thirdLength
              ? (maxWidth - thirdLength * maxNodeWidth) / (thirdLength - 1)
              : (maxWidth - thirdLength * maxNodeWidth) / (thirdLength + 1);
          // 保持大致位置顺序不变
          secondArr.sort(function(a, b) {
            return a.x - b.x;
          });
          for (let s = 0; s < thirdLength; s++) {
            currentLevelPosX +=
              maxLength === thirdLength && s === 0 ? 0 : currentLevelDis;
            const oldModel = JSON.parse(JSON.stringify(secondArr[s]));
            const newModel = JSON.parse(JSON.stringify(oldModel));
            newModel.x = currentLevelPosX;
            newModel.y = currentLevelPosY;
            L_graph.update(newModel.id, newModel);
            currentLevelPosX += maxNodeWidth;
          }
          currentLevelPosY += nodeDisY;
        }
        currentWholeLevelPosX += maxWidth;
      }
      L_graph.fitView(20); // 满屏
      resolv(true);
    });
  };

  //---------------------------------------------------------------
  private btnZoomIn = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolv => {
      const currentZoom = this.GT_editor.G_graph.getZoom();
      this.GT_editor.G_graph.zoomTo(currentZoom + 0.5, this.getViewCenter());
      resolv(true);
    });
  };

  private btnZoomOut = (
    obj?: N_oFlowchart.I_toolbarClick
  ): Promise<boolean> => {
    return new Promise(resolv => {
      const currentZoom = this.GT_editor.G_graph.getZoom();
      this.GT_editor.G_graph.zoomTo(currentZoom - 0.5, this.getViewCenter());
      resolv(true);
    });
  };

  private getViewCenter() {
    const L_graph = this.GT_editor.G_graph;
    const padding = this.getFormatPadding();

    const width = L_graph.get('width');
    const height = L_graph.get('height');
    return {
      x: (width - padding[2] - padding[3]) / 2 + padding[3],
      y: (height - padding[0] - padding[2]) / 2 + padding[0]
    };
  }

  private getFormatPadding(): any {
    const L_graph = this.GT_editor.G_graph;
    return G6.Util.formatPadding(L_graph.get('fitViewPadding'));
  }

  public btnAutoZoom = (
    obj?: N_oFlowchart.I_toolbarClick
  ): Promise<boolean> => {
    return new Promise(resolv => {
      this.GT_editor.G_graph.fitView(20);
      resolv(true);
    });
  };

  public btnResetZoom = (
    obj?: N_oFlowchart.I_toolbarClick
  ): Promise<boolean> => {
    return new Promise(resolv => {
      this.GT_editor.G_graph.zoomTo(1, this.getViewCenter());
      resolv(true);
    });
  };

  private btnGrid = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolv => {
      this.changeGridState(obj.key);
      resolv(true);
    });
  };

  private changeGridState(name: string) {
    const L_graph = this.GT_editor.G_graph;
    const L_editToolbar = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `editToolbar`
    );
    const L_isOpen: boolean = L_editToolbar.G_toolMap.get(name).isOpen;
    if (L_isOpen) {
      L_graph.removePlugin(this.G_grid);
    } else {
      this.G_grid = new G6.Grid();
      L_graph.addPlugin(this.G_grid);
    }
    this.setBtnChickedStyle(name, !L_isOpen);
  }

  private btnAlign = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolv => {
      this.changeItemAlignType(obj.key);
      resolv(true);
    });
  };

  private changeItemAlignType(name: string) {
    const L_graph = this.GT_editor.G_graph;
    const L_editToolbar = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `editToolbar`
    );
    const L_isOpen: boolean = L_editToolbar.G_toolMap.get(name).isOpen;
    if (L_isOpen) {
      L_graph.removePlugin(this.G_itemAlignType);
    } else {
      this.G_itemAlignType = new G6.SnapLine();
      L_graph.addPlugin(this.G_itemAlignType);
    }
    this.setBtnChickedStyle(name, !L_isOpen);
  }

  private btnLevelDown = (obj: {
    key: string;
    Teditor: I_editor;
  }): Promise<boolean> => {
    return new Promise(resolv => {
      const L_selectedItems = this.GT_editor.getSelectedItems();
      if (L_selectedItems && L_selectedItems.length > 0) {
        L_selectedItems.forEach(item => {
          item.toBack();
          this.GT_editor.G_graph.paint();
        });
        resolv(true);
      }
      resolv(false);
    });
  };

  private btnLevelUp = (
    obj?: N_oFlowchart.I_toolbarClick
  ): Promise<boolean> => {
    return new Promise(resolv => {
      const L_selectedItems = this.GT_editor.getSelectedItems();
      if (L_selectedItems && L_selectedItems.length > 0) {
        L_selectedItems.forEach(item => {
          if (item.getType() === 'edge') {
            item.toFront();
            item.getSource().toFront();
            item.getTarget().toFront();
          } else {
            item.toFront();
          }
          this.GT_editor.G_graph.paint();
        });
        resolv(true);
      }
      resolv(false);
    });
  };

  private btnDelete = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolv => {
      const L_selectItems = this.GT_editor.getSelectedItems();
      if (Array.isArray(L_selectItems) && L_selectItems.length > 0) {
        this.GT_editor.executeCommand('delete', L_selectItems);
        this.GT_editor.cleanSelectedItems();
        this.setBtnDisabled(obj.key, true);
        resolv(true);
      }
      resolv(false);
    });
  };

  private btnCopy = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolve => {
      resolve(true);
    });
  };

  private btnPaste = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolve => {
      resolve(true);
    });
  };

  private btnSave = (obj?: N_oFlowchart.I_toolbarClick): Promise<boolean> => {
    return new Promise(resolve => {
      // if (this.GT_editor.G_graph.getNodes().length === 0) {
      //   throw new Error(`无意义的保存没有图形数据`);
      //   resolve(false);
      // throw new Error(' 无意义的保存没有图形数据');
      // }
      resolve(true);
    });
  };

  private btnCancelEdit = (
    obj?: N_oFlowchart.I_toolbarClick
  ): Promise<boolean> => {
    return new Promise(resolve => {
      resolve(true);
    });
  };

  public saveMode = () => {
    const self = this;
    // 保存按钮
    self.setBtnDisabled(`save`, true);
    self.setBtnDisabled(`new`, false);
    // self.setBtnDisabled(`edit`, false);
    self.setEditBtnDisabled(false);
    // 删除按钮
    self.setBtnDisabled(`delete`, true);
    this.setBtnDisabled(`layout`, true); // 排版
    // this.setBtnDisabled(`wyRuleComp`, false); // 编译按扭 改为外部通过this.GT_edirot.
    // 画面行为模式为default
    self.GT_editor.setGraphMode(`default`);
    // 清除撤销重做数据
    self.GT_editor.clearGraphStack();
    // 清除选择数据
    self.GT_editor.cancelAllSelectItem();
    // 元素列表状态
    this.GT_compBox.getCompMergeName(this.G_compID, `item`).setItemDisabledAll(
      true
    );
    self.setAuditBtnDisabled(false);
    self.GT_editor.editorState = `none`;
    this.GT_editor.G_oFlowchart.isExpand = false;
  };

  // 审核按扭状态
  public setAuditBtnDisabled(s: boolean, cmd?: string) {
    if (cmd === `all`) {
      this.setBtnDisabled(`audit`, s);
      this.setBtnDisabled(`unAudit`, s);
      return;
    }
    this.setBtnDisabled(`audit`, s);
    this.setBtnDisabled(`unAudit`, !s);
  }

  private setEditBtnDisabled(p: boolean) {
    this.setBtnDisabled(`edit`, p); // 显示编辑
    this.setBtnDisabled('cancelEdit', !p);
  }

  // 状态控制
  public setBtnDisabled(btnKey: string, s: boolean) {
    const toolbar = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `editToolbar`
    );
    const L_toolMap = toolbar?.G_toolMap;
    if (L_toolMap) {
      if (L_toolMap.has(btnKey)) {
        // 前处理
        switch (btnKey) {
          case 'delete':
            if (!this.deleteRule(s)) {
              return;
            }
            break;
          default:
        }
        L_toolMap.get(btnKey).disabled = s;
      }
    }
  }

  // 隐藏按钮
  public setBtnHide(btnKey: string, s: boolean) {
    const toolbar = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `editToolbar`
    );
    const L_toolMap = toolbar?.G_toolMap;
    if (L_toolMap) {
      if (L_toolMap.has(btnKey)) {
        // 前处理
        switch (btnKey) {
          case 'delete':
            if (!this.deleteRule(s)) {
              return;
            }
            break;
          default:
        }
        L_toolMap.get(btnKey).isHide = s;
      }
    }
  }

  deleteRule(s: boolean): boolean {
    const L_graph = this.GT_editor.G_graph;

    // 是非编辑模式不能开启删除按钮
    if (L_graph.getCurrentMode() !== `edit` && !s) {
      return false;
    }
    return true;
  }

  setBtnChickedStyle(btnKey: string, s: boolean) {
    const L_toolMap = this.GT_compBox.getCompMergeName(
      this.G_compID,
      `editToolbar`
    ).G_toolMap;
    if (L_toolMap.has(btnKey)) {
      L_toolMap.get(btnKey).isOpen = s;
    }
  }

  handleDelete() {
    this.btnsRegFn('delete', this.btnDelete, null, {
      deletedItmes: this.GT_editor.getSelectedItems().map(x => {
        return { id: x.getID(), type: x.getType() };
      })
    });
  }

  handleUndo() {
    this.GT_editor.G_graph.getUndoStack().length > 0 &&
      this.btnsRegFn(`undo`, this.btnUndo);
  }

  handleRedo() {
    this.GT_editor.G_graph.getRedoStack().length > 0 &&
      this.btnsRegFn(`redo`, this.btnRedo);
  }

  private graphToolbarClick(item, e) {
    const key: string = item.key;
    switch (key) {
      case 'undo':
        this.btnsRegFn(key, this.btnUndo);
        break;
      case 'redo':
        this.btnsRegFn(key, this.btnRedo);
        break;
      case 'open':
        this.btnsRegFn(key, this.btnOpen);
        break;
      case 'save':
        this.btnsRegFn(
          key,
          this.btnSave,
          this.saveMode,
          this.GT_editor.doSave()
        );
        break;
      case 'copy':
        this.btnsRegFn(key, this.btnCopy);
        break;
      case 'paste':
        this.btnsRegFn(key, this.btnPaste);
        break;
      case 'delete':
        this.btnsRegFn(key, this.btnDelete, null, {
          deletedItmes: this.GT_editor.getSelectedItems().map(x => {
            return { id: x.getID(), type: x.getType() };
          })
        });
        break;
      case 'zoomIn':
        this.btnsRegFn(key, this.btnZoomIn);
        break;
      case 'zoomOut':
        this.btnsRegFn(key, this.btnZoomOut);
        break;
      case 'autoZoom':
        this.btnsRegFn(key, this.btnAutoZoom);
        break;
      case 'actualSize':
        this.btnsRegFn(key, this.btnResetZoom);
        break;
      case 'levelDown':
        this.btnsRegFn(key, this.btnLevelDown);
        break;
      case 'livelUp':
        this.btnsRegFn(key, this.btnLevelUp);
        break;
      case 'grid':
        this.btnsRegFn(key, this.btnGrid);
        break;
      case 'align':
        this.btnsRegFn(key, this.btnAlign);
        break;
      case 'layout':
        this.btnsRegFn(key, this.btnLayout);
        break;
      case 'new':
        this.btnsRegFn(key, this.btnNew);
        break;
      case 'edit':
        this.btnsRegFn(key, this.btnEdit, this.setEditMode);
        break;
      case 'cancelEdit':
        this.btnsRegFn(
          key,
          this.btnCancelEdit,
          this.saveMode,
          this.GT_editor.restOldValue
        );

        break;
      case 'audit':
        this.btnsRegFn(key, this.btnAudit);
        break;
      case 'unAudit':
        this.btnsRegFn(key, this.btnUnAudit);
        break;
      case 'nav': // 地图导航
        this.btnsRegFn(key, this.btnNavMap);
        break;
      case 'fullScreen':
        this.btnsRegFn(key, this.fullScreen);
        break;
      default:
        this.btnsRegFn(key);
        break;
    }
  }

  // 调用自定义方法
  private btnsRegFn(
    key: string, // 按钮名
    doExec?: N_oFlowchart.TA_regFn, // 标准按钮执行函数
    eventCallback?: Function, // 标准按钮执行回调
    e?: any // 其它挂载通过onToolbarClick传父组件
  ) {
    const L_p: N_oFlowchart.I_toolbarClick = {
      key,
      Teditor: this.GT_editor,
      e
    };
    const befFN = this.GT_editor.getRegFn(`before_${key}`); // before注册函数(obj:any)=>Permise<boolean>
    const doFN = doExec || this.GT_editor.getRegFn(`do_${key}`); // do_xx注册函数(obj:any)=>Permise<boolean>
    const aftFN = this.GT_editor.getRegFn(`after_${key}`); // after注册函数(obj:any)=>Permise<boolean>
    befFN &&
      this.execFunction<N_oFlowchart.I_toolbarClick>(L_p, befFN).then(r => {
        r &&
        doFN && // 执行doFN
          this.execFunction<N_oFlowchart.I_toolbarClick>(L_p, doFN).then(r1 => {
            r1 &&
            aftFN && // 执行aftFN
              this.execFunction<N_oFlowchart.I_toolbarClick>(L_p, aftFN).then(
                r2 => {
                  r2 && eventCallback && eventCallback();
                  r2 && this.onToolbarClick(L_p);
                }
              );
            r1 && !aftFN && eventCallback && eventCallback();
            r1 && !aftFN && this.onToolbarClick(L_p);
          });
        r &&
        !doFN && // 没有doFN 有 aftFN
          aftFN &&
          this.execFunction<N_oFlowchart.I_toolbarClick>(L_p, aftFN).then(
            r3 => {
              r3 && eventCallback && eventCallback();
              r3 && this.onToolbarClick(L_p);
            }
          );
        r && !doFN && !aftFN && eventCallback && eventCallback();
        r && !doFN && !aftFN && this.onToolbarClick(L_p);
      });
    !befFN &&
    doFN && // 无befFN有doFN
      this.execFunction<N_oFlowchart.I_toolbarClick>(L_p, doFN).then(r4 => {
        r4 &&
        aftFN && // 有aftFN
          this.execFunction<N_oFlowchart.I_toolbarClick>(L_p, aftFN).then(
            r5 => {
              r5 && eventCallback && eventCallback();
              r5 && this.onToolbarClick(L_p);
            }
          );
        r4 && !aftFN && eventCallback && eventCallback();
        r4 && !aftFN && this.onToolbarClick(L_p);
      });
    !befFN &&
    !doFN &&
    aftFN && // 无befFN 无doFN 有aftFN
      this.execFunction<N_oFlowchart.I_toolbarClick>(L_p, aftFN).then(r6 => {
        r6 && eventCallback && eventCallback();
        r6 && this.onToolbarClick(L_p);
      });
    !befFN && !doFN && !aftFN && eventCallback && eventCallback();
    !befFN && !doFN && !aftFN && this.onToolbarClick(L_p);
  }

  private async execFunction<T>(
    p: T,
    fn: (_p: any) => Promise<boolean>
  ): Promise<boolean> {
    return await fn(p);
  }

  private onToolbarClick(p: N_oFlowchart.I_toolbarClick) {
    // 发送点击事件
    this.GT_editor.G_oFlowchart.onGraphToolbarClick(p);
  }
}
export { T_graphToolbar };
export interface I_graphToolbar extends T_graphToolbar {}
